home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / DevTools / ClassEditor.0.4 / Source / CEMethod.m < prev    next >
Encoding:
Text File  |  1995-06-07  |  7.2 KB  |  315 lines

  1. /* CEMethod.m                 
  2.  *
  3.  * This object controls the data of a beaker (molecules, cameras, groups etc.)
  4.  * It is the main document of BeakerBoy and controls everything from loading to
  5.  * setting up the browser which does most of the other work.
  6.  *
  7.  * For interface-info see the header file. The comments in this file mostly
  8.  * cover only the real implementation details.
  9.  *
  10.  * Written by:         Thomas Engel
  11.  * Created:            23.10.1993 (Copyleft)
  12.  * Last modified:     12.11.1994
  13.  */
  14.  
  15. #define CURRENT_VERSION 1
  16.  
  17. #import <CEMethod.h>
  18.  
  19. #import <misckit/MiscString.h>
  20.  
  21. @implementation CEMethod
  22.  
  23. + initialize
  24. {
  25.     if ( self == [CEMethod class] )
  26.         [CEMethod setVersion:CURRENT_VERSION];
  27.  
  28.     return self;
  29. }
  30.  
  31. - init
  32. {
  33.     [super init];
  34.     return [self initFromText:[MiscString newWithString:"- myMethod:sender"]];
  35.     
  36.     // BUG BUG..memory leak !
  37. }
  38.  
  39. - initFromText:theLine
  40. {
  41.     // We will create a new method that stores the given string
  42.     // representation.
  43.     // The method name WILL be changed to conform to the following
  44.     // example..as far as spaces ar concerned:
  45.     //
  46.     // old: -  ( char*)getStringFor: (aType) string   andMore:(char *) this ;
  47.     // new: - (char *)getStringFor:(aType)string andMore:(char *)this
  48.     
  49.     id    tokens;
  50.     int i;
  51.     id    tempString;
  52.     int    parts;
  53.     
  54.     [super init];
  55.     name = [MiscString new];
  56.     [name takeStringValue:theLine];
  57.     
  58.     // removing the "\" sign should be enough to support basic RTF source
  59.     // properly.
  60.     
  61.     [name replaceEveryOccurrenceOf:";" with:" "];
  62.     [name replaceEveryOccurrenceOf:"\\" with:" "];
  63.     [name trimWhiteSpaces];
  64.     [name squashSpaces];
  65.  
  66.     // Now charAt:0 _MUST_ be the method type !!
  67.     
  68.     selectorName = [MiscString new];
  69.     tokens = [self methodTokens];
  70.     parts = 0;
  71.     
  72.     for( i=0; i<[tokens count]; i++ )
  73.     {
  74.         tempString = [tokens objectAt:i];
  75.         if( [tempString grep:":"] )
  76.         {
  77.             [selectorName concatenate:tempString];
  78.             parts++;
  79.         }
  80.     }
  81.     // Now if we haven't add even one part...this method has only one. And we
  82.     // have to use at least that one. It has to be the last string because we
  83.     // can't have valid parameters anyway..right...
  84.     
  85.     if( parts == 0 ) [selectorName concatenate:
  86.                             [tokens objectAt:[tokens count]-1]];
  87.                             
  88.     [[tokens freeObjects] free];
  89.     
  90.     return self;
  91. }
  92.  
  93. - free
  94. {
  95.     [name free];
  96.     [selectorName free];
  97.     return [super free];
  98. }
  99.  
  100. - (const char *)name
  101. {
  102.     return [name stringValue];
  103. }
  104.  
  105. - (const char *)selectorName
  106. {
  107.     return [selectorName stringValue];
  108. }
  109.  
  110. - methodTokens
  111. {
  112.     // this method returns a list htat contains the single tokens of this
  113.     // method. like: (BOOL), set:, (char *), aString
  114.     // The receiver has to free the method !
  115.     
  116.     int    i;
  117.     id    tokens;
  118.     id    aString;
  119.     BOOL    isCast;
  120.     char    current;
  121.     
  122.     // First let's tokenize according to the braces and spaces.
  123.     // Remember that the method should be clean right now. Only Spaces.
  124.     // And only one at a time.
  125.     // It will be simpler to dangle trought the string by hand...then
  126.     // finding some cool tokenize-regex combination.
  127.     
  128.     tokens = [List new];
  129.     
  130.     isCast = NO;
  131.     aString = [MiscString new];
  132.     
  133.     for( i=2; i<[name length]; i++ )
  134.     {
  135.         // Now lets check the differnt type of tokens...
  136.         // First lets split them at the places where they have 
  137.     
  138.         current = [name charAt:i];
  139.         [aString addChar:current];
  140.         
  141.         // Now if we find a "(" we will start parsing a cast. Until we find a 
  142.         // ")" we will add everything we find.
  143.         
  144.         if( current == '(' )
  145.         {
  146.             isCast = YES;
  147.         }
  148.         else if( current == ')' )
  149.         {
  150.             [tokens addObject:aString];
  151.             aString = [MiscString new];
  152.             isCast = NO;    
  153.         }
  154.         // Finding a ":" means that we will add a selector.
  155.         
  156.         else if( current == ':' )
  157.         {
  158.             [tokens addObject:aString];
  159.             aString = [MiscString new];
  160.         }
  161.         // Now given tha fact that we can only have one Space at the time
  162.         // this must be the end of a parameter is it is not part of a cast.
  163.         // sure..we sould remove the space from the string before adding it.
  164.         
  165.         else if( current == ' ' && 
  166.                  isCast == NO )
  167.         {
  168.             [aString trimSpaces];
  169.             if( [aString emptyString] == NO )
  170.             {
  171.                 [tokens addObject:aString];
  172.                 aString = [MiscString new];
  173.             }
  174.         }
  175.     }
  176.     
  177.     // If there is something inside the string we will add it to the
  178.     // tokens. This is to be sure that we catch all the parts.
  179.     
  180.     if( [aString emptyString] == NO )
  181.         [tokens addObject:aString];
  182.  
  183.     return tokens;
  184. }
  185.  
  186. - (int)numberOfArguments
  187. {
  188.     // returns the number of arguments this method takes.
  189.     
  190.     return [selectorName numOfChar:':'];
  191. }
  192.  
  193. - (BOOL)isInstanceMethod
  194. {
  195.     if( [name charAt:0] == '+' ) return NO;
  196.     return YES;
  197. }
  198.  
  199. // dragging handling
  200.  
  201. - dragImage
  202. {
  203.     if( [self isInstanceMethod] )
  204.         return [NXImage findImageNamed:"InstanceMethod"];
  205.         
  206.     return [NXImage findImageNamed:"ClassMethod"];
  207. }
  208.  
  209. - (const char *)dragImageTitle
  210. {
  211.     return [self selectorName];
  212. }
  213.  
  214. - prepareDraggingPboard:aPboard
  215. {
  216.     return [self copyTo:aPboard];
  217. }
  218.  
  219. - copy
  220. {
  221.     return self;
  222. }
  223.  
  224. - copyTo:aPasteboard
  225. {
  226.     NXAtom textTypes[5];
  227.     NXStream  *textStream;
  228.     
  229.     textTypes[0] = NXRTFPboardType;
  230.     textTypes[1] = NXAsciiPboardType;
  231.     textTypes[2] = NULL;
  232.     [aPasteboard declareTypes:textTypes num:2 owner:self];
  233.  
  234.     // Just write the selector...this might be useful for creating references !
  235.     // It is not intended to be absolutely cool in the future.
  236.     // In the future we will place some kind of object ref on the pasteboard
  237.     // and perhaps even the whole source when we do ASCII / RTF drags.
  238.     
  239.     // First lets put down the RTF version..
  240.     
  241.     textStream = NXOpenMemory( NULL, 0, NX_WRITEONLY );
  242.      NXPrintf( textStream, "{\\rtf0\\ansi{\\fonttbl" );
  243.      NXPrintf( textStream, "\\f0\\fnil Symbol;" );
  244.      NXPrintf( textStream, "\\f1\\fnil Times-Roman;" );
  245.      NXPrintf( textStream, "\\f2\\fnil Times-Bold;" );
  246.     NXPrintf( textStream, "}\n" );
  247.     
  248.     NXPrintf( textStream, "\\f0\\fs28 " );
  249.     NXPrintf( textStream, "-" );
  250.     NXPrintf( textStream, "\\f1 " );
  251.     NXPrintf( textStream, " " );
  252.     NXPrintf( textStream, "\\f2 " );
  253.     NXPrintf( textStream, [self selectorName] );
  254.     NXPrintf( textStream, "\\f1 " );
  255.     NXPrintf( textStream, ", " );
  256.     NXPrintf( textStream, "}" );
  257.     
  258.     [aPasteboard writeType:NXRTFPboardType fromStream:textStream];
  259.  
  260.     NXCloseMemory( textStream, NX_FREEBUFFER );        
  261.     
  262.     // Now write the ASCII version..
  263.     
  264.     textStream = NXOpenMemory( NULL, 0, NX_WRITEONLY );
  265.     NXPrintf( textStream, "- " );
  266.     NXPrintf( textStream, [self selectorName] );
  267.     NXPrintf( textStream, ", " );
  268.     
  269.     [aPasteboard writeType:NXAsciiPboardType fromStream:textStream];
  270.  
  271.     NXCloseMemory( textStream, NX_FREEBUFFER );        
  272.  
  273.     return self;
  274. }
  275.  
  276. // we are conform to the MiscCompare protocol...actuall all we have is
  277. // a single compare method.
  278.  
  279. - (int)compare:anObject
  280. {
  281.     // Compares the to selectors...caseSensitive !
  282.     // BUG: We will only compare to other methods...but don't chack for that !    
  283.  
  284.     return [selectorName cmp:[anObject selectorName]];
  285. }
  286.  
  287. - (int)compare:anObject ignoreCase:(BOOL)flag 
  288. { return [self compare:anObject];
  289. }
  290. - (int)compare:anObject length:(unsigned long)length
  291. { return [self compare:anObject];
  292. }
  293. - (int)compare:anObject length:(unsigned long)length ignoreCase:(BOOL)flag
  294. { return [self compare:anObject];
  295. }
  296. - (int)compareLiteral:(const char *)literal
  297. { return 0;
  298. }
  299. - (int)compareLiteral:(const char *)literal ignoreCase:(BOOL)flag
  300. { return 0;
  301. }
  302. - (int)compareLiteral:(const char *)literal length:(unsigned long)length
  303. { return 0;
  304. }
  305. - (int)compareLiteral:(const char *)literal length:(unsigned long)length ignoreCase:(BOOL)flag
  306. { return 0;
  307. }
  308. @end
  309.  
  310. /*
  311.  * History: 13.01.95 Buh
  312.  *            
  313.  *
  314.  * Bugs: - ...
  315.  */